import 'package:flutter/foundation.dart';
import 'package:loxen/api/api.dart';
import 'package:loxen/api/http_server/user_comment.dart';
import 'package:loxen/api/http_server/user_follower.dart';
import 'package:loxen/api/http_util.dart';
import 'package:loxen/mode/base_mode.dart';
import 'package:loxen/mode/comment_list.dart';
import 'package:loxen/mode/comment_mode.dart';
import 'package:loxen/mode/study/like_study_bean.dart';
import 'package:loxen/mode/study/study_info_bean.dart';
import 'package:loxen/utils/html_util.dart';
import 'package:loxen/utils/string_res.dart';
import 'package:loxen/viewmode/base_view_model.dart';
import 'package:rxdart/rxdart.dart';

class StudyDetailViewModel extends BaseViewModel with UserFollowerMixin, UserCommentMixin {
  StudyInfo _contentBean;
  StudyInfo _pStudyInfo;
  List<StudyInfo> _likeStudy;
  int currentCategory;
  int commentCount;
  String _videoUrl;

  int pageSize = 3;
  int _commentPage = 1;
  int _opacity = 0;
  double _presetOffset = 200.0;

  List<Comment> comments = [];

  List<StudyInfo> get likeStudy => _likeStudy;

  String get videoUrl => _videoUrl;

  List<String> types = ['knowledge', 'case'];

  StudyDetailViewModel(this._pStudyInfo, this.currentCategory);

  StudyInfo get contentBean => _contentBean;

  int get opacity => _opacity;

  void changeEntity() {
    notifyListeners();
  }

  void unLikeCollection(StudyInfo entity) {
    String type;
    if (currentCategory == 0) {
      type = 'study-knowledge';
    } else {
      type = 'study-case';
    }
    ApiService.unCollection(type, entity.id.toString()).listen((event) {
      if (event.statusCode == 200) {
        entity.is_collect = 0;
        entity.collect_num -= 1;
        notifyListeners();
      }
    }, onError: (error, stack) {
      print(error);
      print(stack);
    });
  }

  void collection() {
    _contentBean.collect_num += 1;
    _contentBean.is_collect = 1;
    _pStudyInfo.collect_num += 1;
    _pStudyInfo.is_collect = 1;
    notifyListeners();
  }

  void unCollection(Function(String msg) onShow) {
    String type;
    if (currentCategory == 0) {
      type = 'study-knowledge';
    } else {
      type = 'study-case';
    }
    ApiService.unCollection(type, _contentBean.id.toString()).listen((event) {
      if (event.statusCode == 200) {
        _pStudyInfo.is_collect = 0;
        _pStudyInfo.collect_num -= 1;
        _contentBean.is_collect = 0;
        _contentBean.collect_num -= 1;
        onShow.call(StringResources.qu_xiao_shou_cang);
        notifyListeners();
      } else {
        onShow.call(StringResources.qu_xiao_shou_cang_shi_bai);
      }
    }, onError: (error, stack) {
      onShow.call(StringResources.wang_luo_yi_chang);
      print(error);
      print(stack);
    });
  }

  //取消点赞
  void unLikeComment(Comment comment) {
    ApiService.unLikeComment("${comment.id}").listen((event) {
      if (event.statusCode == 200) {
        comment.is_like = 0;
        comment.likes_num -= 1;
        notifyListeners();
      }
    }, onError: (error) => print(error));
  }

  //评论点赞
  void likeComment(Comment comment) {
    ApiService.likeComment("${comment.id}").listen((event) {
      if (event.statusCode == 201) {
        comment.is_like = 1;
        comment.likes_num += 1;
        notifyListeners();
      }
    }, onError: (error) => print(error));
  }

  //是否有下一页评论
  bool isNextComment() {
    return _commentPage * pageSize < commentCount ?? false;
  }

  //下一页评论数据
  void nextComment() {
    if (isNextComment()) {
      _commentPage++;
      loadComment();
    }
  }

  //是否有下一页子评论
  bool isNextSubComment(Comment comment) {
    return comment.subPage * pageSize < comment.sub_comment_num;
  }

  void nextSubComment(Comment comment) {
    if (isNextSubComment(comment)) {
      comment.subPage += 1;
      loadSubComment(comment);
    }
  }

  //加载子评论列表
  void loadSubComment(Comment comment) {
    ApiService.commentList("${comment.id}", "${comment.subPage}", pageSize: pageSize.toString())
        .flatMap((value) => compute(decodeComment, value.data).asStream())
        .listen((event) {
      List<Comment> newList = [];
      newList.addAll(comment.sub_comment);
      newList.addAll(event.data.results);
      comment.sub_comment = newList;
    }, onError: (error) => print(error), onDone: () => notifyListeners());
  }

  //加载评论数据
  void loadComment() {
    ApiService.studyComment(_pStudyInfo.id.toString(), "$_commentPage",
            pageSize: pageSize.toString())
        .flatMap((value) => compute(decodeComment, value.data).asStream())
        .listen(
      (event) {
        List<Comment> newList = [];
        event.data.results.forEach((element) {
          element.sub_comment = [];
          loadSubComment(element);
        });
        newList.addAll(comments);
        newList.addAll(event.data.results);
        comments = newList;
        commentCount = event.data.count;
      },
      onError: (error) => print(error),
      onDone: () => notifyListeners(),
    );
  }

  //标题栏透明度
  void changeColor(double offset) {
    _opacity = offset > _presetOffset ? 255 : offset * 255 ~/ _presetOffset;
    notifyListeners();
  }

  //关注当前文章作者
  void followThisUser({Function(String error) onError}) {
    followerUser(_contentBean.user.id.toString()).listen((event) {
      if (event == 201) {
        _contentBean.user.isFollowed = 1;
        notifyListeners();
      } else {
        if (onError != null) onError.call('关注失败');
      }
    }, onError: (error, stack) {
      print(error);
      print(stack);
      if (onError != null) onError.call('网络异常');
    });
  }

  //关注当前文章作者
  void unFollowThisUser({Function(String error) onError}) {
    unFollowerUser(_contentBean.user.id.toString()).listen((event) {
      if (event == 200) {
        _contentBean.user.isFollowed = 0;
        notifyListeners();
      } else {
        if (onError != null) onError.call('取消失败');
      }
    }, onError: (error, stack) {
      print(error);
      print(stack);
      if (onError != null) onError.call('网络异常');
    });
  }

  void deleteCommentNotify(Comment comment,
      {Function(String msg) onError, bool isSub = false, Comment params}) {
    deleteComment('study-knowledge', contentBean.id.toString(), comment.id.toString()).listen(
        (event) {
      if (event == 200) {
        if (isSub) {
          var subList = params.sub_comment;
          subList.remove(comment);
          params.sub_comment = subList.take(subList.length).toList();
        } else {
          comments.remove(comment);
          comments = comments.take(comments.length).toList();
        }
        commentCount -= 1;
        notifyListeners();
      } else {
        if (onError != null) onError.call("删除失败！");
      }
    }, onError: (error) {
      if (onError != null) onError.call("网络异常");
      print(error);
    });
  }

  //评论当前文章
  void commentThis(String content) {
    ApiService.commentStudy(_pStudyInfo.id.toString(), content)
        .flatMap((value) => compute(decodeSendComment, value.data).asStream())
        .listen((event) {
      if (event.data != null) {
        List<Comment> list = [event.data];
        list.addAll(comments);
        comments = list;
        commentCount += 1;
        _contentBean.comment_num += 1;
        _pStudyInfo.comment_num += 1;
        notifyListeners();
      }
    }, onError: (error) => print(error));
  }

  void commentToComment(Comment comment, String content,
      {Comment params, Function(String msg) onError}) {
    ApiService.commentStudy(_pStudyInfo.id.toString(), content,
            parent: params != null ? params.id.toString() : comment.id.toString(),
            previousComment: comment.id.toString())
        .flatMap((value) => compute(decodeSendComment, value.data).asStream())
        .listen((event) {
      if (event.data != null) {
        List<Comment> list = [];
        list.add(event.data);
        if (params == null) {
          comment.sub_comment_num += 1;
          if (comment.sub_comment != null) {
            list.addAll(comment.sub_comment);
          }
          comment.sub_comment = list;
        } else {
          params.sub_comment_num += 1;
          if (params.sub_comment != null) {
            list.addAll(params.sub_comment);
          }
          params.sub_comment = list;
        }
        commentCount += 1;
        notifyListeners();
      } else {
        if (onError != null) onError.call('评论失败');
      }
    }, onError: (error) {
      if (error is ServiceException) {
        var map = error.data as Map;
        if (onError != null) onError.call(map['data']['instance_id'].toString());
      }
    });
  }

  //当前文章点赞
  void likeThis() {
    ApiService.likeStudy(_contentBean.id.toString(), types[currentCategory]).listen((event) {
      _contentBean.is_like = 1;
      _contentBean.like_num += 1;
      _pStudyInfo.is_like = 1;
      if (_pStudyInfo.like_num != null) {
        _pStudyInfo.like_num += 1;
      }
      notifyListeners();
    }, onError: (error) => print(error));
  }

  //当前文章取消点赞
  void unLikeThis() {
    ApiService.unLikeStudy(_contentBean.id.toString(), types[currentCategory]).listen((event) {
      _contentBean.is_like = 0;
      _contentBean.like_num -= 1;
      _pStudyInfo.is_like = 0;
      if (_pStudyInfo.like_num != null) {
        _pStudyInfo.like_num -= 1;
      }
      notifyListeners();
    }, onError: (error) => print(error));
  }

  // 猜你喜欢
  void loadLikeStudy() {
    ApiService.guessLikeStudy(
            types[currentCategory], "${_contentBean.category}", "${_contentBean.id}")
        .flatMap((value) => compute(decodeLikeStudy, value.data).asStream())
        .listen((event) {
      _likeStudy = event.data.results;
    }, onError: (error) => print(error), onDone: () => notifyListeners());
  }

  //猜你喜欢文章点赞
  void likeToLikeStudy(StudyInfo likeStudy) {
    ApiService.likeStudy(likeStudy.id.toString(), types[currentCategory]).listen((event) {
      likeStudy.is_like = 1;
      likeStudy.like_num += 1;
      notifyListeners();
    }, onError: (error) => print(error));
  }

  //猜你喜欢文章取消点赞
  void unLikeToLikeStudy(StudyInfo likeStudy) {
    ApiService.unLikeStudy(likeStudy.id.toString(), types[currentCategory]).listen((event) {
      likeStudy.is_like = 0;
      likeStudy.like_num -= 1;
      notifyListeners();
    }, onError: (error) => print(error));
  }

  // 加载内容数据
  void loadContent({void Function() onSuccess}) {
    if (mState == BaseState.LOADING) return;
    ApiService.studyContent(_pStudyInfo.id.toString(), types[currentCategory])
        .doOnListen(() {
          mState = BaseState.LOADING;
        })
        .flatMap((value) => compute(decodeContent, value.data).asStream())
        .listen((event) async {
          if (event != null && event.data != null) {
            _contentBean = event.data;
            _contentBean.contentList = await HtmlUtil.parseHtml(_contentBean.content);
            _contentBean.content = null;
            _videoUrl = event.data.video?.video_url;
            if (_likeStudy == null) loadLikeStudy();
            mState = BaseState.CONTENT;
          } else {
            mState = BaseState.EMPTY;
          }
        }, onError: (error) {
          print(error);
          mState = BaseState.FAIL;
        }, onDone: () {
          notifyListeners();
          if (onSuccess != null) onSuccess.call();
        });
  }

  static LikeStudyBean decodeLikeStudy(dynamic json) {
    return LikeStudyBean.fromJson(json);
  }

  static BaseMode<Comment> decodeSendComment(dynamic json) {
    return BaseMode<Comment>(json);
  }

  static BaseMode<StudyInfo> decodeContent(dynamic json) {
    return BaseMode<StudyInfo>(json);
  }

  static BaseMode<CommentList> decodeComment(dynamic json) {
    return BaseMode<CommentList>(json);
  }
}
